package xin.nick.demo;

import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author Nick
 * @since 2022/7/6/006
 */
public class HandleWord {

    public static String stringFlag = "$";

    public static void main(String[] args) throws IOException {
        // 需要读取的文件
        String filePath = "word_template.docx";
        String outFilePath = "D:\\tmp\\demo_out.docx";


        HandleWord handleWord = new HandleWord();
        URL resource = handleWord.getClass().getResource("/");
        filePath = resource.getPath() + filePath;
        handleWord.checkPassed(filePath);

        Map<String, String> flagValueMap = handleWord.getFlagValueMap();
        handleWord.handle(filePath, outFilePath, flagValueMap);
    }

    public void handle(String filePath, String outFilePath, Map<String, String> flagValueMap) throws IOException {

        //解析docx模板并获取document对象
        XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        //获取整个文本对象
        List<XWPFParagraph> paragraphList = document.getParagraphs();

        //获取所有的段落
        for (XWPFParagraph xwpfParagraph : paragraphList) {

            // 如果段落文本包含需要替换的,执行替换
            String paragraphText = xwpfParagraph.getText();

            if(checkText(paragraphText)){
                System.out.println("/ " + xwpfParagraph.getText());
                List<XWPFRun> runList = xwpfParagraph.getRuns();
                for (XWPFRun xwpfRun : runList) {
                    // 执行替换
                    String runText = xwpfRun.toString();
                    if(checkText(runText)){
                        String newRunText = changeValue(runText, flagValueMap);
                        System.out.println("- " + runText);
                        xwpfRun.setText(newRunText,0);
                        System.out.println("+ " + xwpfRun.toString());
                    }
                }
                System.out.println("* " + xwpfParagraph.getText());
            }
        }

        //生成新的word
        File file = new File(outFilePath);
        FileOutputStream stream = new FileOutputStream(file);
        document.write(stream);
        stream.close();

        // 导出 pdf
        PdfOptions pdfOptions = PdfOptions.create();
        String outPdfFilePath = "D:\\tmp\\demo_temp\\demo_out.pdf";
        OutputStream outPdf = new FileOutputStream(outPdfFilePath);
        PdfConverter.getInstance().convert(document,  outPdf, pdfOptions);
        outPdf.close();
    }

    /**
     * 判断文本中时候包含$
     * @param text 文本
     * @return 包含返回true,不包含返回false
     */
    public static boolean checkText(String text){
        boolean check  =  false;
        if (Objects.isNull(text)) {
            return false;
        }
        if(text.indexOf(stringFlag)!= -1){
            check = true;
        }
        return check;
    }

    /**
     * 匹配传入信息集合与模板
     * @param value 模板需要替换的区域
     * @param flagValueMap 传入标记集合
     * @return 模板需要替换区域信息集合对应值
     */
    public String changeValue(String value, Map<String, String> flagValueMap){

        if (Objects.isNull(value)) {
            return "";
        }

        Set<Map.Entry<String, String>> textSets = flagValueMap.entrySet();
        for (Map.Entry<String, String> textSet : textSets) {
            // 匹配模板 进行替换 格式${{key}}
            String key = "${{"+textSet.getKey()+"}}";
            if(value.indexOf(key)!= -1){
                value = value.replace(key, textSet.getValue());
            }
        }

        // 未匹配返回空
        if(checkText(value)){
            value = "";
        }
        return value;
    }

    public Map<String, String> getFlagValueMap() {
        Map<String, String> flagValueMap = new HashMap<>(4);
        flagValueMap.put("tempName", "0001");
        flagValueMap.put("toDay", "0002");
        flagValueMap.put("bigTitle", "0003");
        flagValueMap.put("username", "0004");
        return flagValueMap;
    }


    /**
     * 检查是否合格
     * @param filePath
     */
    public void checkPassed(String filePath) throws IOException {
        //解析docx模板并获取document对象
        XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(filePath));
        //获取整个文本对象
        List<XWPFParagraph> paragraphList = document.getParagraphs();

        //获取所有的段落
        for (XWPFParagraph xwpfParagraph : paragraphList) {

            // 遍历检查
            String paragraphText = xwpfParagraph.getText();
            if(checkText(paragraphText)){
                System.out.println("/ " + xwpfParagraph.getText());
                List<XWPFRun> runList = xwpfParagraph.getRuns();
                for (XWPFRun xwpfRun : runList) {
                    String runText = xwpfRun.toString();
                    if(checkText(runText)) {
                        System.out.println("- " + runText);
                    }
                }

            }
        }
    }

}
